#include "GridBasedSampler.h"
#include <cstdlib>
#include <stdio.h>

GridBasedSampler::GridBasedSampler(float gridSize)
	: currentCellIndex(-1), cellSize_(0.01f), gridSize_(gridSize)
{
}


GridBasedSampler::~GridBasedSampler(void)
{
}

void GridBasedSampler::setBounds(int left, int right, int top, int bottom, float radius)
{
	Sampler::setBounds(left, right, top, bottom, radius);

	cellSize_ = gridSize_;// * 0.2f / radius;
	cellCountX_ = (int)ceilf(widthX_ / cellSize_);
	cellCountY_ = (int)ceilf(widthY_ / cellSize_);
	printf("cellSize : %f\n", cellSize_);

	unoccupiedCells_.resize(cellCountX_ * cellCountY_);
	for (int i = 0; i < cellCountX_ * cellCountY_; ++i)
		unoccupiedCells_[i] = i;
}

Vector2 GridBasedSampler::sample()
{
	if (unoccupiedCells_.size() == 0)
		resetUnoccupiedCells();

	++currentCellIndex;
	if (currentCellIndex >= unoccupiedCells_.size())
		currentCellIndex = 0;

	float cellX = (unoccupiedCells_[currentCellIndex] % cellCountX_) * cellSize_;
	float cellY = (unoccupiedCells_[currentCellIndex] / cellCountX_) * cellSize_;

	float maxX = cellSize_;
	float maxY = cellSize_;
	if (cellX + maxX > widthX_)
		maxX = widthX_ - cellX;
	if (cellY + maxY > widthY_)
		maxY = widthY_ - cellY;

	Vector2 ret;
	ret._x = (float)minX_ + cellX + ((float)rand() / RAND_MAX) * maxX;
	ret._y = (float)minY_ + cellY + ((float)rand() / RAND_MAX) * maxY;

	return ret;
}

void GridBasedSampler::lastSampleClearFeedback(bool value)
{
	if (currentCellIndex == -1)
		return;

	static int failureCount = 0;
	static int counter = 0;
	if (value)
	{
		unoccupiedCells_[currentCellIndex] = unoccupiedCells_.back();
		unoccupiedCells_.resize(unoccupiedCells_.size() - 1);

		failureCount = 0;
	}
	else
	{
		if (++failureCount > unoccupiedCells_.size() * 10 && currentCellIndex >= unoccupiedCells_.size() - 1)
			resetUnoccupiedCells();
	}
	if (counter % 1000 == 0)
		printf("# of unoccupied cells : %d\n", unoccupiedCells_.size());
	++counter;
	
	
}

void GridBasedSampler::resetUnoccupiedCells()
{
	// reset
	unoccupiedCells_.resize(cellCountX_ * cellCountY_);
	for (int i = 0; i < cellCountX_ * cellCountY_; ++i)
		unoccupiedCells_[i] = i;
	if (currentCellIndex >= unoccupiedCells_.size())
		currentCellIndex = -1;
}